package com.hb.common.util;

import cn.hutool.core.io.resource.ResourceUtil;
import com.hb.common.constant.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * JAR包工具类
 */
public class JarUtil {

    private static final Logger log = LoggerFactory.getLogger(JarUtil.class);

    /**
     * 根据class从lib文件夹获取jar包路径
     */
    public static String  getJarPathFromLib(Class cls){
        URL url = cls.getProtectionDomain().getCodeSource().getLocation();
        String path = url.getFile();
        if (System.getProperty("os.name").contains("dows")) {
            if (path.indexOf("/") == 0) {
                path = path.substring(path.indexOf("/") + 1);
            }
        }
        return path;
    }


    /**
     * 获取运行环境，lib打包方式
     */
    public static int getRunEnviron(Class cls) {
        String path = cls.getProtectionDomain().getCodeSource().getLocation().getPath();
        if (path.contains(".jar")) {
            if (path.contains("!/")) {
                //jar模式运行,lib放在jar里面
                return Config.ON_JAR_LIB_INSIDE;
            } else {
                //jar模式运行,lib放在jar外面
                return Config.ON_JAR_LIB_OUTSIDE;
            }
        } else {
            //idea模式运行
            return Config.NOT_JAR;
        }
    }

    /**
     * 获取类所在的jar的系统路径
     */
    public static String getJarFilePath(Class cls) {
        URL url = cls.getProtectionDomain().getCodeSource().getLocation();
        String path = url.getFile();
        if (path.contains("!/")) {
            path = path.substring(path.indexOf("/"));
        }
        if (path.contains("!")) {
            path = path.substring(0, path.indexOf("!"));
        }
        if (System.getProperty("os.name").contains("windows")) {
            if (path.indexOf("/") == 0) {
                path = path.substring(path.indexOf("/") + 1);
            }
        }
        return path;
    }


    /**
     * 获取Jar包里面的文件流
     *
     * @param jarFilePath jar路径
     * @param name        xx结尾的文件名
     */
    public static InputStream getJarInputStream(String jarFilePath, String name) throws Exception {
        JarFile jarFile = new JarFile(new File(jarFilePath));
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            String entryName = entry.getName();
            if (entryName.endsWith("classes/")) {
                return jarFile.getInputStream(jarFile.getEntry(entryName + name));
            }
        }
        throw new Exception(jarFilePath + "里找不到" + name + "文件");
    }


    public static InputStream getInputStream(Class cls,String fileName) {
        try {
            //判断打包方式
            switch (JarUtil.getRunEnviron(cls)){
                case Config.NOT_JAR:
                    //idea模式
                    return ResourceUtil.getStream(fileName);
                case Config.ON_JAR_LIB_OUTSIDE:
                    //lib依赖放在jar外面
                    //获取zip所在的jar的位置
                    String libJarFile=JarUtil.getJarPathFromLib(cls);
                    return JarUtil.getJarInputStream(libJarFile, fileName);
                case Config.ON_JAR_LIB_INSIDE:
                    //lib依赖放在jar里面
                    //获取启动类所在的jar文件路径
                    String jarFilePath=JarUtil.getJarFilePath(cls);
                    return JarUtil.getJarInputStream(jarFilePath, fileName);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

}